<template>
  <div>
    <!-- todo: ':val' is set as workaround for update not being fired on props change.. -->
    <canvas
      :style="{height: size + 'px', width: size + 'px'}"
      :height="size"
      :width="size"
      ref="qr"
      :val="val"
      class="can"
    ></canvas>
  </div>
</template>


<script>
  import qr from './qr/index'
  /* eslint-disable */
  export default {
    props: {
      val: {
        type: String,
        required: true
      },
      size: {
        type: Number,
        default: 100
      },
      // 'L', 'M', 'Q', 'H'
      level: String,
      bgColor: {
        type: String,
        default: '#FFFFFF'
      },
      fgColor: {
        type: String,
        default: '#000000'
      }
    },
    beforeUpdate() {
      this.update()
    },
    mounted() {
      this.update()
    },
    methods: {
      getUrl(url) {
        this.$emit('getUrl', url)
      },
      update() {
        const { size } = this
        const { bgColor } = this
        const { fgColor } = this
        const $qr = this.$refs.qr

        const qrcode = qr(this.val)

        const ctx = $qr.getContext('2d')
        const cells = qrcode.modules
        const tileW = size / cells.length
        const tileH = size / cells.length
        const scale = (window.devicePixelRatio || 1) / getBackingStorePixelRatio(ctx)

        $qr.height = $qr.width = size * scale
        ctx.scale(scale, scale)

        cells.forEach((row, rdx) => {
          row.forEach((cell, cdx) => {
            ctx.fillStyle = cell ? fgColor : bgColor
            const w = (Math.ceil((cdx + 1) * tileW) - Math.floor(cdx * tileW))
            const h = (Math.ceil((rdx + 1) * tileH) - Math.floor(rdx * tileH))
            ctx.fillRect(Math.round(cdx * tileW), Math.round(rdx * tileH), w, h)
          })
        })
        this.getUrl($qr.toDataURL('image/jpg'))
      }
    }
  }

  function getBackingStorePixelRatio(ctx) {
    return (
      ctx.webkitBackingStorePixelRatio
      || ctx.mozBackingStorePixelRatio
      || ctx.msBackingStorePixelRatio
      || ctx.oBackingStorePixelRatio
      || ctx.backingStorePixelRatio
      || 1
    )
  }

</script>
